package com.spark.sql

import org.apache.spark.SparkConf
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.{DataFrame, Dataset, Row, SparkSession}

/**
  *
  * @author Pop
  * @date 2022/7/20 22:48
  */
object Spark01_SparkSql_Basic {
  def main(args: Array[String]): Unit = {

    // 创建SparkSql的运行环境
    val sparkSql: SparkConf = new SparkConf().setMaster("local[*]").setAppName("sparkSql")
    val session: SparkSession = SparkSession.builder().config(sparkSql).getOrCreate()
    import session.implicits._
    // 执行逻辑操作
//      val df: DataFrame = session.read.json("datas/user.json")
//      df.show
    // DataFrame =》 Sql
//    DataFrame2Sql(df,session)

    // DataFrame =》 DSL
//    DataFrame2Dsl(df)
    // DataSet
    val ints: Seq[Int] = Seq(1,2,3,4)
    val ds: Dataset[Int] = ints.toDS
    ds.show()

    // RDD <=> DataFrame
    // DataFrame 其实一种特殊的类型的DataSet，源码中也是这样展示的
    // type DataFrame = org.apache.spark.sql.Dataset[org.apache.spark.sql.Row]
    val rdd: RDD[(Int, String, Int)] = session.sparkContext.makeRDD(List((1,"zhangsan",30),(2,"lisi",40)))
    val df: DataFrame = rdd.toDF("id","name","age")

    val rowRdd: RDD[Row] = df.rdd
    // DataFrame <=>DataSet
    val ds1: Dataset[User] = df.as[User]
    val df1: DataFrame = df.toDF()

    // RDD 《=》DataSet
    // DataSet需要类型，但是RDD是只关心数据的，所以我们需要类型
    val users: RDD[User] = rdd.map {
      case (id, name, age) => User(id, name, age)
    }
    val ds3: Dataset[User] = users.toDS()
    val rdd4: RDD[User] = ds3.rdd
    // 关闭环境
    sparkSql.clone()
  }

  case class User(id:Int,name:String,age:Int){

  }

  private def DataFrame2Dsl(df: DataFrame, session:SparkSession) = {
    df.select("age", "username").show
    // 在使用  DataFrame时，如果涉及到转换操作，需要引入转换规则
    import session.implicits._
    df.select($"age" + 1).show
    df.select('age + 1).show
  }

  def DataFrame2Sql(df:DataFrame, session:SparkSession):Unit = {
    df.createOrReplaceTempView("user")
    session.sql("select * from user").show
    session.sql("select age from user").show
    session.sql("select avg(age) from user").show
  }
}
